//
//  MePayment.m
//  MeAppBox
//
//  Created by absir on 12-5-16.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "AES128.h"
#import "MePayment.h"

//字符串处理
#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (AESAdditions)

- (NSData *)subDataFromDest:(char *)dest To:(char *)to
{
	NSUInteger len = [self length];
    
    
	char* buffer = (char *)malloc(len+1);
	[self getBytes:buffer length:len];
    
    NSData* data = NULL;
	char* start=strstr(buffer,dest);
    if(start){
        start += strlen(dest);
        dest=strstr(start,to);
        if(dest) data=[NSData dataWithBytes:start length:(dest-start)];
    }
    
	free(buffer);
	return data;
}

- (NSData *)dataBase64Encode
{
	size_t outputLength;
	char *outputBuffer = NewBase64Encode([self bytes], [self length], true, &outputLength);
	NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength];
	free(outputBuffer);
	return result;
}

- (NSString *)stringBase64Encode
{
    size_t outputLength;
	char *outputBuffer = NewBase64Encode([self bytes], [self length], true, &outputLength);
	NSString *result = [NSString stringWithUTF8String:outputBuffer];
	free(outputBuffer);
	return result;
}

- (NSData *)dataBase64Decode
{
	size_t outputLength;
	char *outputBuffer = (char *)NewBase64Decode((char *)[self bytes], [self length], &outputLength);
	NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength];
	free(outputBuffer);
	return result;
}

- (NSData *)AES128EncryptWithKey:(NSString *)key {
	// 'key' should be 16 bytes for AES128, will be null-padded otherwise
	char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
	bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
	
	// fetch key data
	[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
	
	NSUInteger dataLength = [self length];
	//set kCCOptionECBMode padding
	NSUInteger datalength2=ceil(dataLength/16.0)*16;
	
	//See the doc: For block ciphers, the output size will always be less than or
	//equal to the input size plus the size of one block.
	//That's why we need to add the size of one block here
	size_t bufferSize = dataLength + kCCBlockSizeAES128;
	void *buffer = malloc(bufferSize);
	
	size_t numBytesEncrypted = 0;
	CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode,
										  keyPtr, kCCKeySizeAES128,
										  NULL /* initialization vector (optional) */,
										  [self bytes], datalength2, /* input */
										  buffer, bufferSize, /* output */
										  &numBytesEncrypted);
	if (cryptStatus == kCCSuccess) {
		//the returned NSData takes ownership of the buffer and will free it on deallocation
		return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        //free(buffer);
        //return result;
        //return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
	}
	
	free(buffer); //free the buffer;
	return nil;
}

- (NSData *)AES128DecryptWithKey:(NSString *)key {
	// 'key' should be 16 bytes for AES128, will be null-padded otherwise
	char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
	bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
	
	// fetch key data
	[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
	
	NSUInteger dataLength = [self length];
	
	//See the doc: For block ciphers, the output size will always be less than or
	//equal to the input size plus the size of one block.
	//That's why we need to add the size of one block here
	size_t bufferSize = dataLength + kCCBlockSizeAES128;
	void *buffer = malloc(bufferSize);
	
	size_t numBytesDecrypted = 0;
	CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode,
										  keyPtr, kCCKeySizeAES128,
										  NULL /* initialization vector (optional) */,
										  [self bytes], dataLength, /* input */
										  buffer, bufferSize, /* output */
										  &numBytesDecrypted);
	
	if (cryptStatus == kCCSuccess) {
		//the returned NSData takes ownership of the buffer and will free it on deallocation
		return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
        //free(buffer);
        //return result;
	}
	
	free(buffer); //free the buffer;
	return nil;
}

@end


@implementation MePayment
@synthesize status = status_;
@synthesize products = products_;
@synthesize callFunc = callFunc_;

static id _shared_ = NULL;
//静态返回
+ (id)shared
{
	@synchronized(self)
	{
		if (!_shared_)
			_shared_ = [[self alloc] init];
		return _shared_;
	}
}

//是否可以付费
+ (BOOL)canPayment
{
    return [SKPaymentQueue canMakePayments];
}

//对象初始化
-(id)init
{
    if ((self = [super init])) {
        
        //监听购买结果    
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
        
    }
    return self;    
}    

//释放对象
-(void)dealloc    
{    
    [loadingText_ release];
    [products_ release];
    [callFunc_ release];
    
    //解除监听
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    
    (self==_shared_)&&(_shared_ = NULL);
    [super dealloc];    
}    

//子线程载入提示
- (void)loadingText:(NSString *)text
{
    loop_ = TRUE;
    [text retain];
    [loadingText_ release];
    loadingText_ = text;
}

//读取
static BOOL _SKPaymented_ = FALSE;
static BOOL _isPaymented_ = FALSE;
- (void)readProduct:(NSString *)product
{
    [self readProducts:[NSSet setWithObject:product]];
}
- (void)readProducts:(NSSet *)products
{
    if(_SKPaymented_){
//        [AppWindow alertMessage:@"程序购买运行中!"];
        return;
    }
    
    _SKPaymented_ = TRUE;
    
    if(![SKPaymentQueue canMakePayments]){
//        [AppWindow alertMessage:@"应用程序内不允许购买!"];
        return;
    }
    
    SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers:products];    
    request.delegate=self;    
    [request start];
    
//    if(callFunc_) loop_ = FALSE;
    
    if(loop_ && loadingText_){
//        [AppWindow loadingWindow:loadingText_ Type:0 Data:NULL];
    }
    while (loop_) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
    if(loadingText_){
        [loadingText_ release];
        loadingText_ = NULL;
//        [AppWindow loadingWindowRemoveType:0];
    }
}

//购买
- (int)buyProduct:(NSString *)product
{
    _isPaymented_ = TRUE;
    
    status_ = _ePyt_Failed;
    
    [self readProduct:product];
    
    return status_;
}

//购买行为委托
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response 
{
    self.products = response.products;
    
    if(_isPaymented_){
        
        _isPaymented_ = FALSE;
        
        if([products_ count]){
            [[SKPaymentQueue defaultQueue] addPayment:[SKPayment paymentWithProduct:[products_ objectAtIndex:0]]];
        }else{
//            [AppWindow alertMessage:@"该商品不存在!"];
        
//            loop_ = FALSE;
        }
//
//    }else{
//        
//        _SKPaymented_ = FALSE;
        
//        if(callFunc_){
//            [callFunc_ execute:products_];
//            self.callFunc = NULL;
//        }
        
        loop_ = FALSE;
    }
}

- (void)paymentTransactionPurchased:(SKPaymentTransaction *)transaction
{
//    AppServer *server = [AppServer shared];
//    [server loadingText:NULL];
    
    SKPayment *payment = transaction.payment;
    NSString *invoice = [[[NSString alloc] initWithData:[transaction.transactionReceipt dataBase64Decode] encoding:NSUTF8StringEncoding] autorelease];
    
//    NSMutableDictionary *resDic;
//    int resCode;
//    
//    resDic = [NSMutableDictionary dictionary];
//    [resDic setObject:payment.productIdentifier forKey:@"productId"];
//    [resDic setObject:[NSNumber numberWithUnsignedInt:payment.quantity] forKey:@"quantity"];
//    [resDic setObject:invoice forKey:@"invoice"];
//    [server getDataFromPath:@"verify/verifyAppleInvoice" Att:NULL Body:resDic Post:TRUE];
//    [server parserResponse:&resCode];
    
//    if(resCode==1) status_ = _ePyt_Success;
    
//    if(callFunc_){
//        [callFunc_ execute:invoice];
//        self.callFunc = NULL;
//    }

}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for(SKPaymentTransaction *transaction in transactions){
        
        _SKPaymented_ = loop_ = FALSE;
       
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchased:
                [callFunc_ payResult: 0:transaction.transactionIdentifier :[transaction.transactionReceipt base64Encoding] :@""];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                // [SKPaymentQueue ]
                //[self paymentTransactionPurchased:transaction];
                break;
            case SKPaymentTransactionStateRestored:
//                [AppWindow alertMessage:@"已经购买过该商品"];
                [callFunc_ payResult: 1:transaction.transactionIdentifier :[transaction.transactionReceipt base64Encoding] :@"已经购买过该商品"];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                NSLog(@"已经购买过该商品");
                break;
            case SKPaymentTransactionStatePurchasing:
                loop_ = TRUE;
                break;
            default:
//                [AppWindow alertMessage:@"交易失败"];
                NSLog(@"交易失败");
                //NSLog(@"error:%@",transaction.error.description);
                [callFunc_ payResult: 3:transaction.transactionIdentifier :[transaction.transactionReceipt base64Encoding] :transaction.error.description];
                break;
        }
    }
}

@end
